package com.godenwater.recv.server.summit;

import com.godenwater.core.container.Module;
import com.godenwater.core.spring.Application;
import com.godenwater.core.spring.BaseDao;
import com.godenwater.recv.manager.MessageManager;
import com.godenwater.recv.manager.MonitorManager;
import com.godenwater.recv.manager.SessionManager;
import com.godenwater.recv.manager.TaskManager;
import com.godenwater.recv.server.szy206.ConnectionManager;
import com.godenwater.recv.server.szy206.SzyHelp;
import com.godenwater.recv.utils.TaskEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 西安山脉协议接收服务器，此为单独运行时所用！
 */
public class SummitServer {

    private static Logger logger = LoggerFactory.getLogger(SummitServer.class);

    private long startDate = System.currentTimeMillis();
    private String host;
    private boolean initialized = false;
    private boolean started = false;
    // ----------------------------------------------------------------------


    /**
     * All modules loaded by this server
     */
    private Map<Class, Module> modules = new LinkedHashMap<Class, Module>();

    private ClassLoader loader;


    // 创建10个生产线程，使用线程池的方式，可以保障线程的安全性。
    ExecutorService service = Executors.newFixedThreadPool(10);

    // 计数
    public final AtomicInteger wc = new AtomicInteger();

    /**
     * 传输消息最大数量
     */
    public static final int MAX_SERIAL = 65535;

    // 定义所管理的测站列表
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");

    private static SummitServer instance;

    private boolean RUNNING = false;

    /**
     * Returns a singleton instance of XMPPServer.
     *
     * @return an instance.
     */
    public static SummitServer getInstance() {
        if (instance == null) {
            instance = new SummitServer();
        }
        return instance;
    }

    /**
     * Creates a server and starts it.
     */
    private SummitServer() {
        if (instance != null) {
            throw new IllegalStateException("RTU SUMMIT server is already running");
        }
        instance = this;
    }

    /**
     * 初始化数据
     */
    public void initialize() {

        startDate = System.currentTimeMillis();
        loader = Thread.currentThread().getContextClassLoader();

    }

    /**
     * 加载内部模块
     */
    private void loadModules() {

        loadModule(SummitConnectionManager.class.getName()); // 加载内部连接管理
        loadModule(SessionManager.class.getName()); // 加载内部连接管理

        //loadModule(StationCacheManager.class.getName()); // 加载所有测站信息
        loadModule(MessageManager.class.getName()); // 加载报文管理
        loadModule(TaskManager.class.getName()); // 加载内部连接管理
        //loadModule(LogManager.class.getName()); //加载内部连接管理

        loadModule(MonitorManager.class.getName()); // 加载监控终端管理器
    }

    /**
     * 加载模块
     *
     * @param module
     */
    private void loadModule(String module) {
        System.out.println(">> Load " + module + "...");
        try {
            Class modClass = loader.loadClass(module);
            Module mod = (Module) modClass.newInstance();
            this.modules.put(modClass, mod);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("admin.error", e);
        }
    }

    private void initModules() {
        for (Module module : modules.values()) {
            boolean isInitialized = false;
            try {
                module.initialize();
                isInitialized = true;
            } catch (Exception e) {
                e.printStackTrace();
                this.modules.remove(module.getClass());
                if (isInitialized) {
                    module.stop();
                    module.destroy();
                }
                logger.error("admin.error", e);
            }
        }
    }

    private void startModules() {
        for (Module module : modules.values()) {
            boolean started = false;
            try {
                module.start();
            } catch (Exception e) {
                if (started && module != null) {
                    module.stop();
                    module.destroy();
                }
                logger.error("admin.error", e);
            }
        }
    }

    public SessionManager getSessionManager() {
        return (SessionManager) modules.get(SessionManager.class);
    }
    public ConnectionManager getConnectionManager() {
        return (ConnectionManager) modules.get(ConnectionManager.class);
    }
    public MonitorManager getMonitorManager() {
        return (MonitorManager) modules.get(MonitorManager.class);
    }

    /**
     * 启动服务实例
     */
    public void start() {

        try {
            initialize();
            // load all the modules
            loadModules();
            // Initize all the modules
            initModules();
            // Start all the modules
            startModules();

            //---------------------------

            RUNNING = true;

            // service.execute(new MessageConsumer(this));
            // service.execute(new CombinConsumer(this));
            // service.execute(new RtuDatabaseConsumer(this));
            // service.execute(new BizDatabaseConsumer(this));

            System.out.println("SUMMIT SERVER >> Startup.");

            startDate = System.currentTimeMillis();
            started = true;

        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage(), e);
            System.out.println("startup.error");
            // shutdownServer();
        }

    }

    /**
     * 关闭服务实例
     */
    public void stop() {

        RUNNING = false;
        try {
            Thread.sleep(3 * 1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        service.shutdown();
        // service.shutdownNow();
        System.out.println("正在关闭处理服务，请等待....");
        try {
            Thread.sleep(3 * 1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // If we don't have modules then the server has already been shutdown
        if (modules.isEmpty()) {
            return;
        }
        // Get all modules and stop and destroy them
        for (Module module : modules.values()) {
            module.stop();
            module.destroy();
        }
        modules.clear();

        TaskEngine.getInstance().shutdown();

        System.out.println("RTU SERVER >> Shutting down...");
    }

    public boolean running() {
        return RUNNING;
    }

    /**
     * 检查数据库是否异常
     *
     * @return
     */
    public boolean verifyDb() {
        BaseDao dao = (BaseDao) Application.getInstance().getBean("baseDao");
        java.sql.Connection conn;
        try {
            conn = dao.getDataSource().getConnection();

            if (conn.isClosed()) {
                return false;
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return true;
    }

    public long getStartDate() {
        return startDate;
    }

    /**
     * 获取消息总数
     *
     * @return
     */
    public int messageSize() {
        if (wc.get() == Integer.MAX_VALUE) {
            wc.set(0);
        }
        return wc.incrementAndGet();
    }

    // private synchronized void createListeners() {
    // createTcpListener();
    // createUdpListener();
    // createGsmListener();
    // createPstnListener();
    // createCommListener();
    // }

    public static void main(String[] args) {
        SummitServer server = SummitServer.getInstance();
        server.start();
        InputStreamReader is = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(is);
        try {
            String cmd = "";

            boolean flag = true;
            System.out.print("CMD>>");
            while (flag) {
                cmd = br.readLine();
                if (cmd.equalsIgnoreCase("exit")
                        || cmd.equalsIgnoreCase("quit")) {
                    server.stop();
                    flag = false;
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.exit(0);

                } else if (cmd.equalsIgnoreCase("help")) {
                    SzyHelp.printHelp();
                } else if (cmd.equalsIgnoreCase("client")) {

                }   else {
                    //server.sendCommand(cmd);
                }

                System.out.print("CMD>>");
            }

        } catch (IOException e) {
            System.out.println("系统错误！");
            e.printStackTrace();
        } finally {
            try {
                is.close();
                br.close();
            } catch (IOException e) {
                System.out.println("关闭流发生错误！");
                e.printStackTrace();
            }
        }
    }

}
